<template>
  <view class="water-progress-container" :style="{ width: size + 'rpx', height: size + 'rpx' }">
    <canvas type="2d" id="waterProgressCanvas" class="water-progress-canvas"
      :style="{ width: size + 'rpx', height: size + 'rpx' }"></canvas>
    <view class="progress-text">
      <slot></slot>
    </view>
  </view>
</template>

<script>
export default {
  name: 'WaterProgress',
  props: {
    // 当前值
    current: {
      type: Number,
      default: 0
    },
    // 目标值
    goal: {
      type: Number,
      default: 2000
    },
    // 组件大小
    size: {
      type: Number,
      default: 300
    },
    // 进度条颜色
    progressColor: {
      type: String,
      default: '#2196F3'
    },
    // 背景颜色
    backgroundColor: {
      type: String,
      default: '#E0E0E0'
    },
    // 线宽
    lineWidth: {
      type: Number,
      default: 15
    }
  },
  data() {
    return {
      ctx: null,
      canvasWidth: 0,
      canvasHeight: 0,
      animationTimer: null,
      currentAngle: 0,
      targetAngle: 0
    }
  },
  computed: {
    // 计算进度百分比
    percent() {
      return Math.min(100, Math.round((this.current / this.goal) * 100))
    },
    // 计算目标角度
    angle() {
      return (this.percent / 100) * Math.PI * 2
    }
  },
  watch: {
    // 监听当前值变化，更新进度条
    current() {
      this.updateProgress()
    },
    // 监听目标值变化，更新进度条
    goal() {
      this.updateProgress()
    }
  },
  mounted() {
    this.initCanvas()
  },
  beforeUnmount() {
    // 清除动画定时器
    if (this.animationTimer) {
      clearTimeout(this.animationTimer)
    }
  },
  methods: {
    // 初始化Canvas
    initCanvas() {
      const query = uni.createSelectorQuery().in(this)
      query.select('#waterProgressCanvas')
        .fields({ node: true, size: true })
        .exec(res => {
          if (res[0]) {
            const canvas = res[0].node
            const ctx = canvas.getContext('2d')
            
            // 设置画布尺寸
            const dpr = uni.getSystemInfoSync().pixelRatio
            canvas.width = res[0].width * dpr
            canvas.height = res[0].height * dpr
            
            this.ctx = ctx
            this.canvasWidth = canvas.width
            this.canvasHeight = canvas.height
            
            // 缩放以适应DPR
            ctx.scale(dpr, dpr)
            
            // 初始绘制
            this.targetAngle = this.angle
            this.drawProgress(0)
            
            // 启动动画
            this.animateProgress()
          }
        })
    },
    
    // 更新进度
    updateProgress() {
      // 设置目标角度
      this.targetAngle = this.angle
      
      // 如果没有动画在运行，启动动画
      if (!this.animationTimer) {
        this.animateProgress()
      }
    },
    
    // 绘制进度条
    drawProgress(angle) {
      if (!this.ctx) return
      
      const ctx = this.ctx
      const centerX = this.canvasWidth / (2 * uni.getSystemInfoSync().pixelRatio)
      const centerY = this.canvasHeight / (2 * uni.getSystemInfoSync().pixelRatio)
      const radius = (Math.min(centerX, centerY) - this.lineWidth / 2)
      
      // 清除画布
      ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
      
      // 绘制背景圆环
      ctx.beginPath()
      ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)
      ctx.strokeStyle = this.backgroundColor
      ctx.lineWidth = this.lineWidth
      ctx.stroke()
      
      // 绘制进度圆环
      if (angle > 0) {
        ctx.beginPath()
        ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + angle)
        ctx.strokeStyle = this.progressColor
        ctx.lineWidth = this.lineWidth
        ctx.stroke()
      }
    },
    
    // 进度条动画
    animateProgress() {
      // 清除之前的定时器
      if (this.animationTimer) {
        clearTimeout(this.animationTimer)
        this.animationTimer = null
      }
      
      // 如果当前角度已经达到目标角度，不需要动画
      if (Math.abs(this.currentAngle - this.targetAngle) < 0.01) {
        this.currentAngle = this.targetAngle
        this.drawProgress(this.currentAngle)
        return
      }
      
      // 计算下一帧的角度
      const step = (this.targetAngle - this.currentAngle) * 0.1
      this.currentAngle += step
      
      // 绘制当前帧
      this.drawProgress(this.currentAngle)
      
      // 继续下一帧
      this.animationTimer = setTimeout(() => {
        this.animateProgress()
      }, 16)
    }
  }
}
</script>

<style scoped>
.water-progress-container {
  position: relative;
  margin: 0 auto;
}

.water-progress-canvas {
  position: absolute;
  top: 0;
  left: 0;
}

.progress-text {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
</style>